//based on pyprser from pydev and javacc compiler compiler.

#ifndef _ABSTRACTPYTHONGRAMMAR_H_
#define _ABSTRACTPYTHONGRAMMAR_H_

#include <QString>
#include "GrammarErrorHandlers.h"
#include "SpecialStr.h"
#include "FastStringBuffer.h"
#include "ast/Str.h"
#include "ast/Num.h"
#include "ast/modType.h"
#include "ast/Import.h"
#include "ast/ImportFrom.h"
#include "ast/Name.h"

class SimpleNode;
class Object;
class JJTState;
class TokensIterator;
class TokenManager;
class CharStream;

class PythonGrammar: public GrammarErrorHandlers
{
public:
    PythonGrammar();
    virtual ~PythonGrammar();

    SimpleNodePtr findTokenToAdd(const TokenPtr& next);
    bool findTokenAndAdd(const QString & token, bool searchOnLast = false);

    virtual QList<ObjectPtr>* getTokenSourceSpecialTokensList() = 0;
    virtual TokenPtr getToken(int index) = 0;

    ObjectPtr temporaryToken;
protected:
    virtual JJTState * getJJTree() = 0;


    void addToPeekCallFunc(const ObjectPtr& t, bool after);

    void addToPeek(const SimpleNodePtr& peeked, const ObjectPtr& t, bool after, Ast::AstTypes class_);
    void addToPeek(const ObjectPtr& t, bool after, Ast::AstTypes class_ = Ast::Object);
    void addToPeek(const QString& t, bool after);

    void jjtreeOpenNodeScope(const SimpleNodePtr& n);
    void jjtreeCloseNodeScope(const SimpleNodePtr& n);

    virtual TokenPtr getCurrentToken() = 0;
    virtual void setCurrentToken(const TokenPtr& t) = 0;
    virtual TokenPtr getJJLastPos() = 0;
    virtual TokenManager* getTokenManager() = 0;
    virtual CharStream* getInputStream() = 0;

    void addSpecialTokenToLastOpened(const ObjectPtr& o);
    void addSpecialTokenToLastOpened(const QString & o);

    void addSpecialToken(const ObjectPtr& o, int strategy = 0);
    void addSpecialToken(const QString & o, int strategy = 0);
    void addSpecialToArgDef(const ObjectPtr& str);

    SpecialStrPtr createSpecialStr(const QString& token, bool searchOnLast=false, bool throwException = true);
    void makeString(const QString & s, int quotes, const SimpleNodePtr& strToFill);
    void makeInt(const QString& s, int radix, const TokenPtr& token, const SimpleNodePtr& numberToFill);
    void makeFloat(const TokenPtr& t, const SimpleNodePtr& numberToFill);
    void makeComplex(const TokenPtr& t, const SimpleNodePtr& numberToFill);
protected:
    SimpleNodePtr prev;
    int STRATEGY_BEFORE_NEXT;
    int STRATEGY_ADD_AFTER_PREV;
    bool DEFAULT_SEARCH_ON_LAST;
    FastStringBuffer dottedNameStringBuffer;
private:
    void addSpecial(const SimpleNodePtr& node, const ObjectPtr& special, bool after);
    TokensIterator* getTokensIterator(const TokenPtr& firstIterationToken, int tokensToIterate, bool breakOnIndentsDedentsAndNewCompounds);
    SpecialStrPtr convertStringToSpecialStr(const ObjectPtr& o);
    int getType(QChar c, int quotes);
    SpecialStrPtr _lastSpecial;
    SimpleNodePtr _lastNodeWithSpecial;
    TokensIterator* _tokensIterator;
};

#endif // ABSTRACTPYTHONGRAMMAR_H
